﻿using System;
using System.Collections.Generic;
using System.Web.Mvc;
using Xenta.Utils;
using Xenta.Attributes;
using Xenta.Web.Controllers;

namespace Xenta.Web.Areas.Commerce.Controllers
{
    [Authenticate, InRole("ADMIN")]
    public sealed class CustomerController : ExtController
    {
        #region GET/POST Actions

        [HttpGet]
        public ActionResult Index()
        {
            return View();
        }

        [HttpGet]
        public ActionResult GoTo(int? id, int? accountID)
        {
            if(!id.HasValue && accountID.HasValue)
            {
                var m = Svc.ProcessOperation("GetCustomerByAccount", new
                {
                    AccountID = accountID
                });
                id = m != null ? JDM.Int32(m.EntityID) : null;
            }
            if(!id.HasValue)
                return HttpNotFound();
            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id
            }));
        }

        [HttpGet, RestoreState]
        public ActionResult Create()
        {
            return View();
        }

        [HttpPost, PersistState]
        public ActionResult Create(int accountID, string[] flags)
        {
            try
            {
                var m = Svc.ProcessOperation("CreateCustomer", new
                {
                    AccountID = accountID,
                    Flags = flags.Merge(",")
                });
                return RedirectToAction(Loc.Act("Edit").Set(new
                {
                    id = JDM.Int32(m.EntityID)
                }));
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Create"));
        }

        [HttpGet, RestoreState]
        public ActionResult Edit(int id)
        {
            var m = Svc.ProcessOperation("GetCustomer", new
            {
                EntityID = id,
            }, new
            {
                DisclosureLevel = "Entire"
            });
            if(m == null)
                return HttpNotFound();
            return View(m);
        }

        [HttpPost, PersistState]
        public ActionResult Update(int id, string[] flags)
        {
            try
            {
                Svc.ProcessOperation("UpdateCustomer", new
                {
                    EntityID = id,
                    Flags = flags.Merge(",")
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }

            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id
            }));
        }

        [HttpGet, PersistState]
        public ActionResult Delete(int id)
        {
            try
            {
                Svc.ProcessOperation("DeleteCustomer", new
                {
                    EntityID = id
                });
                return RedirectToAction(Loc.Act("Index"));
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id
            }));
        }

        [HttpPost, PersistState]
        public ActionResult CreateAddress(int customerID,
            int countryID,
            int regionID,
            string city,
            string address1,
            string address2,
            string entityName,
            string contactName,
            string postalCode,
            string phoneNumber,
            string faxNumber,
            string email,
            string website,
            string[] flags)
        {
            try
            {
                Svc.ProcessOperation("CreateCustomerAddress", new
                {
                    HolderID = customerID,
                    CountryID = countryID,
                    RegionID = regionID,
                    City = city,
                    Address1 = address1,
                    Address2 = address2,
                    EntityName = entityName,
                    ContactName = contactName,
                    PostalCode = postalCode,
                    PhoneNumber = phoneNumber,
                    FaxNumber = faxNumber,
                    Email = email,
                    Website = website,
                    Flags = flags.Merge(",")
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id = customerID
            }));
        }

        [HttpPost, PersistState]
        public ActionResult UpdateAddress(int id,
            int customerID,
            int countryID,
            int regionID,
            string city,
            string address1,
            string address2,
            string entityName,
            string contactName,
            string postalCode,
            string phoneNumber,
            string faxNumber,
            string email,
            string website,
            string[] flags)
        {
            try
            {
                Svc.ProcessOperation("UpdateCustomerAddress", new
                {
                    EntityID = id,
                    CountryID = countryID,
                    RegionID = regionID,
                    City = city,
                    Address1 = address1,
                    Address2 = address2,
                    EntityName = entityName,
                    ContactName = contactName,
                    PostalCode = postalCode,
                    PhoneNumber = phoneNumber,
                    FaxNumber = faxNumber,
                    Email = email,
                    Website = website,
                    Flags = flags.Merge(",")
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id = customerID
            }));
        }

        [HttpGet, PersistState]
        public ActionResult DeleteAddress(int id, int customerID)
        {
            try
            {
                Svc.ProcessOperation("DeleteCustomerAddress", new
                {
                    EntityID = id
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id = customerID
            }));
        }

        #endregion

        #region AJAX Actions

        [HttpPost]
        public ActionResult Grid(int? page,
            int? rows,
            string sord,
            string sidx,
            string searchTerm,
            int? countryID,
            int? regionID)
        {
            page = page.HasValue ? page.Value - 1 : 0;
            rows = rows.HasValue ? rows.Value : 30;
            sord = sord.Equals("desc") ? "Descending" : "Ascending";

            var m = Svc.ProcessOperation("SearchCustomers", new 
            {
                Term = new
                {
                    Expression = searchTerm
                },
                CountryID = countryID,
                RegionID = regionID,
                Index = page * rows,
                Count = rows,
                SortBy = new[] 
                {
                    sidx
                },
                SortDir = sord
            }, new
            {
                DisclosureLevel = "Base"
            });
            var data = new List<Object>();

            foreach(var i in m.Items)
            {
                data.Add(new[] { 
                    JDM.Int32(i.EntityID),
                    JDM.String(i.Account.Email)
                });
            }

            return Json(new
            {
                pageIndex = page + 1,
                pageCount = Math.Ceiling(JDM.Double(m.TotalCount) / rows),
                totalCount = JDM.Int64(m.TotalCount),
                data = data.ToArray()
            });
        }

        [HttpPost]
        public ActionResult Autocomplete(string term)
        {
            var m = Svc.ProcessOperation("GetCustomerDictionary", new
            {
                Term = new
                {
                    Expression = String.Format("{0}%", term)
                },
                Count = 10
            });
            var data = new List<Object>();

            foreach(var i in m.Items)
            {
                data.Add(new
                {
                    id = JDM.String(i.Key),
                    value = JDM.String(i.Value)
                });
            }
            return Json(data.ToArray());
        }

        [HttpPost]
        public ActionResult Addresses(int customerID)
        {
            var m = Svc.ProcessOperation("SearchCustomerAddresses", new
            {
                HolderID = customerID
            }, new
            {
                DisclosureLevel = "Base"
            });
            var data = new List<Object>();

            foreach(var i in m.Items)
            {
                data.Add(new
                {
                    id = JDM.Int32(i.EntityID),
                    value = JDM.String(i.ShortForm)
                });
            }
            return Json(data.ToArray());
        }

        #endregion
    }
}
